package cn.chiship.framework.third.biz.wxpub.controller;

import cn.chiship.framework.common.pojo.vo.ThirdApplicationKeyConfigVo;
import cn.chiship.framework.common.service.impl.GlobalCacheServiceImpl;
import cn.chiship.framework.third.biz.wxpub.service.WeixinService;
import cn.chiship.framework.third.core.common.WechatUtils;
import cn.chiship.sdk.core.annotation.NoParamsSign;
import cn.chiship.sdk.core.annotation.NoVerificationAppIdAndKey;
import cn.chiship.sdk.core.annotation.NoVerificationProjectId;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.exception.custom.BusinessException;
import cn.chiship.sdk.core.util.Base64Util;
import cn.chiship.sdk.core.util.PrintUtil;
import cn.chiship.sdk.core.util.UrlUtil;
import cn.chiship.sdk.core.util.http.ResponseUtil;
import cn.chiship.sdk.third.core.common.ThirdOauthLoginDto;
import cn.chiship.sdk.third.service.WxPubService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lijian
 */
@Controller
@RequestMapping("/wxPub")
@NoParamsSign
@NoVerificationAppIdAndKey
@NoVerificationProjectId
@Api(tags = "微信交互控制器")
public class WxPubController {

    private static final Logger LOGGER = LoggerFactory.getLogger(WxPubController.class);

    @Resource
    private WeixinService weixinService;

    @Resource
    private WxPubService wxPubService;

    @Resource
    GlobalCacheServiceImpl globalCacheService;

    /**
     * 校验
     *
     * @param request
     * @param response
     * @throws
     */
    @ApiOperation(value = "微信校验")
    @GetMapping(produces = "application/json;charset=UTF-8", path = "check/{appId}")
    public void valid(HttpServletRequest request, HttpServletResponse response, @PathVariable(value = "appId") String appId) throws IOException {
        try {
            ThirdApplicationKeyConfigVo applicationKeyConfigVo = globalCacheService.getThirdApplicationConfigByAppId(appId);
            String token = applicationKeyConfigVo.getServerToken();
            wxPubService.validate(request, response, token);
            LOGGER.info("校验成功！");

        } catch (BusinessException businessException) {
            ResponseUtil.write(response, "校验失败");
            LOGGER.error(businessException.getMessage());
        }


    }

    /**
     * 处理微信与微信用户通信
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws DocumentException
     */
    @ApiOperation(value = "处理微信与微信用户通信")
    @PostMapping(produces = "application/xml;charset=UTF-8", path = "check/{appId}")
    public void dispose(HttpServletRequest request, HttpServletResponse response,
                        @PathVariable(value = "appId") String appId) throws IOException, DocumentException {
        response.setCharacterEncoding("UTF-8");
        try {
            wxPubService.config(globalCacheService.getWeiXinConfigByAppId(appId));
            Map<String, String> map = wxPubService.dispose(request);
            PrintUtil.console("收到消息", map);
            String message = weixinService.analysisMessage(map);
            PrintUtil.console("回复消息", message);
            WechatUtils.printlnStr(response, message);
        } catch (BusinessException businessException) {
            ResponseUtil.write(response, "校验失败");
            LOGGER.error(businessException.getMessage());
        }


    }

    @GetMapping("/login")
    public String login(Model model) {
        return "h5/login";
    }

    @ApiOperation(value = "微信认证")
    @PostMapping(value = "authorize")
    public ResponseEntity<BaseResult> wxAuthorize(@RequestBody @Valid ThirdOauthLoginDto thirdOauthLoginDto) {
        return new ResponseEntity<>(weixinService.oauth2Auth(thirdOauthLoginDto), HttpStatus.OK);
    }

    @ApiOperation(value = "微信认证重定向")
    @GetMapping(value = "redirectUri/{appId}")
    public ModelAndView redirectUri(HttpServletRequest request, @PathVariable("appId") String appId) throws Exception {
        String code = request.getParameter("code");
        wxPubService.config(globalCacheService.getWeiXinConfigByAppId(appId)).token();
        BaseResult baseResult = wxPubService.oauth2AccessToken(code);
        LOGGER.info("oauth2AccessToken:{}", JSON.toJSONString(baseResult));
        Map<String, Object> query = new HashMap(8);
        if (baseResult.isSuccess()) {
            JSONObject oauth2AccessTokenJson = (JSONObject) baseResult.getData();
            query.put("openId", oauth2AccessTokenJson.getString("openid"));
        }
        query.put("success", String.valueOf(baseResult.isSuccess()));
        String url = new String(Base64Util.decode(request.getParameter("state")));
        PrintUtil.console(UrlUtil.analyticUrlMap(url));
        String redirectUrl = UrlUtil.buildUrl(url, query);
        redirectUrl = URLDecoder.decode(redirectUrl, BaseConstants.UTF8);
        LOGGER.info("redirectUrl:{}", redirectUrl);
        return new ModelAndView(new RedirectView(redirectUrl));
    }

}
